home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Sound / DelfMPEG / src / DelfMPEG.c < prev    next >
C/C++ Source or Header  |  2000-05-16  |  36KB  |  1,067 lines

  1. /*****************************************************************************
  2.  
  3.     DelfMPEG - MPEG audio player for Delfina DSP
  4.     Copyright (C) 1999, 2000  Michael Henke
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. *****************************************************************************/
  21.  
  22.  
  23. #define DEBUGnot
  24.  
  25.  
  26. #include <proto/exec.h>
  27. #include <proto/dos.h>
  28. #include <proto/asyncio.h>
  29. #include <proto/timer.h>
  30. #include <proto/reqtools.h>
  31. #include <exec/interrupts.h>
  32. #include <exec/execbase.h>
  33. #include <exec/memory.h>
  34. #include <exec/libraries.h>
  35. #include <libraries/asyncio.h>
  36. #include <devices/timer.h>
  37. #include <libraries/reqtools.h>
  38. #include <math.h>
  39. #include <limits.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42.  
  43. static UBYTE version[]="$VER: DelfMPEG 0.4 (Tue 16-May-2000)";
  44. static UBYTE template[]=
  45.  "FILES/M,-V=VERBOSE/S,-N=NOPLAY/S,-T=SHOWTAG/S,-NL=NOFASTL/S,-NP=NOFASTP/S,"
  46.  "-F=FRAMEBUF/K/N,-A=ASYNCBUF/K/N,-FF=FFSKIP/K/N,-NT=NOTIMER/S,-M=MONO/S,"
  47.  "-S=STRICT/S,-D=DACRATE/K/N,-VOL=VOLUME/K/N";
  48.  
  49. #define DEFAULT_FRAMEBUF    100
  50. #define DEFAULT_ASYNCBUF    128
  51. #define DEFAULT_FFSKIP      10
  52.  
  53. struct loadbuf {
  54.     ULONG header;
  55.     UWORD framesize, delfcopysize, crc, III_main_data_size;
  56.     UBYTE layer, mode, modext, freq, errprot, br_ind, II_jsbound, II_translate;
  57.     struct loadbuf *next;
  58.     UBYTE data[1728];   /* max: layer II, 384 kbps, 32 kHz -> 1728-4 bytes */
  59. };
  60.  
  61. struct loadbuf *framebuf0=NULL, *curr_load, *curr_play;
  62. LONG framebuf0size=0;
  63.  
  64. static ULONG mpg_freq[4]={44100,48000,32000,0};
  65. static UBYTE *mpg_modename[4]={"stereo","j-stereo","dual-ch","single-ch"};
  66. static UBYTE *mpg_layername[3]={"I","II","III"};
  67. static UWORD mpg_bitrate[3][16]=
  68.         { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, /* I */
  69.           {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},   /* II */
  70.           {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0} }; /* III */
  71. static UWORD mpg_translate[3][2][16] =
  72.            { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,    /* 44100 stereo */
  73.                { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,  /* 44100 mono   */
  74.              { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,    /* 48000 stereo */
  75.                { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,  /* 48000 mono   */
  76.              { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,    /* 32000 stereo */
  77.                { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } }; /* 32000 mono   */
  78. static UWORD mpg_sblimit[4]={27,30,8,12};
  79.  
  80. static ULONG ID3v1_TAG;
  81. static UBYTE ID3v1_buffer[142];
  82.  
  83. /** static LONG pow43tab[8206]; **/
  84. #include "MP3_pow43tab.h"
  85. /** static LONG quantab[512]; **/
  86. #include "MP3_quantab.h"
  87.  
  88. static UWORD bitres_offset, bitres_ok;
  89. static UBYTE bitres_buffer[4096];
  90.  
  91. #define MPG_MD_STEREO           0
  92. #define MPG_MD_JOINT_STEREO     1
  93. #define MPG_MD_DUAL_CHANNEL     2
  94. #define MPG_MD_MONO             3
  95. #define HDR_MPEG1               0xfff80000
  96. #define HDR_CONSTANT            0x00060c00  /* layer, sampling frequency */
  97. #define ID3V1                   0x54414700  /* TAG */
  98. #define ID3V2                   0x49443300  /* ID3 */
  99. #define XING_FLAG_FRAMES        1
  100.  
  101. static UBYTE *delfina_name[8]=
  102.     { "Classic","Lite","Pro","1200","Plus","UNKNOWN","UNKNOWN","UNKNOWN" };
  103.  
  104. extern struct DelfObj DSP56K_PCM;
  105. extern struct DelfObj DSP56K_MP2;
  106. extern struct DelfObj DSP56K_MP3;
  107.  
  108. #include <libraries/delfina.h>
  109. #include "PCM.h"
  110. #include "MP2.h"
  111. #include "MP3.h"
  112.  
  113. extern struct ExecBase *SysBase;
  114. struct Library *DelfinaBase=NULL;
  115. struct Library *AsyncIOBase=NULL;
  116. struct Library *TimerBase=NULL;
  117. struct ReqToolsBase *ReqToolsBase=NULL;
  118.  
  119. struct AsyncFile *file;
  120. struct FileInfoBlock *fib=NULL;
  121. struct TagItem tag_done={TAG_DONE};
  122. UBYTE rtfilename[128]={0};
  123. struct Task *mytask;
  124. ULONG bytes_total, bytes_loaded, buffers_filled, buffers_missed;
  125. ULONG prevheader, currheader, frames_loaded, frames_played;
  126. ULONG decoder_busy, maindata_err, frames_js;
  127. struct Interrupt delfint={0};
  128. struct DelfPrg *prg_pcm=NULL, *prg_mp2=NULL, *prg_mp3=NULL;
  129. struct DelfModule *mod_pcm=NULL;
  130. DELFPTR mem_il_mp2=NULL, mem_ip_mp2=NULL, mem_y_mp3_quantab=NULL;
  131. DELFPTR mem_il_mp3=NULL, mem_ip_mp3=NULL, mem_x_mp3_ro=NULL;
  132. ULONG key=0;
  133.  
  134. UWORD *gb_pt, gb_buf, gb_num;
  135.  
  136. ULONG xingvbr, xing_flags, xing_frames;
  137. ULONG channels,mono,freq,layer,pause,noplay,showtag;
  138. ULONG verbose, ende=0, havetag, nofastl, nofastp, notimer, forcemono, strict;
  139. LONG framebuf, asyncbuf, ffskip, dacrate, volume;
  140. int rc=0;
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147. /*
  148. **
  149. ** layer III - bit reservoir handling **
  150. **
  151. */
  152. UWORD BitReservoir(struct loadbuf *buf)
  153. {
  154.     UWORD main_data_begin, i;
  155.     UBYTE *p0, *p1;
  156.     p1= &buf->data[0];
  157.     main_data_begin= (UWORD)(*p1)<<1 | (UWORD)(*(p1+1))>>7;
  158.     /*
  159.     ** copy side information **
  160.     */
  161.     p0= &bitres_buffer[0];
  162.     for(i=32; i>0; i--) *p0++= *p1++;
  163.     /*
  164.     ** copy previous main_data **
  165.     */
  166.     p0++; /* &bitres_buffer[33] */
  167.     if(bitres_offset>=main_data_begin)
  168.     {
  169.         bitres_ok=1;
  170.         p1=p0+bitres_offset-main_data_begin;
  171.         for(i=main_data_begin; i>0; i--) *p0++= *p1++;
  172.         bitres_offset=main_data_begin;
  173.     }
  174.     else
  175.     {
  176.         bitres_ok=0;            /* not enough data in reservoir */
  177.         p0+=bitres_offset;
  178.     }
  179.     /*
  180.     ** copy current main_data **
  181.     */
  182.     i= mono ? 17 : 32;          /* side info length */
  183.     p1= &buf->data[i];          /* begin of main_data area */
  184.     i= buf->delfcopysize-i;     /* mainslots */
  185.     bitres_offset+= i;
  186.     for(; i>0; i--) *p0++= *p1++;
  187.     return(bitres_ok);
  188. }
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195. /*
  196. **
  197. ** Delfina interrupt server **
  198. **
  199. */
  200. void IntServer(void)
  201. {
  202.     if(pause)
  203.     {
  204.         /*
  205.         ** mute **
  206.         */
  207.         Delf_Run( prg_pcm->prog+PROG_PCM_MUTE, 99, DRUNF_ASYNCH,
  208.                   0, 0, 0, 0 );
  209.     }
  210.     else
  211.     {
  212.         if(buffers_filled>0)
  213.         {
  214.             switch(layer)
  215.             {
  216.             case 2:
  217.                 if( !Delf_Peek( prg_mp2->ydata+DATY_MP2_BUSY,DMEMF_YDATA ) )
  218.                 {
  219.                     /*
  220.                     ** send framedata to Delfina and launch MP2 decoder **
  221.                     */
  222.                     Delf_CopyMem( &curr_play->data[0],
  223.                                   (void*)(prg_mp2->xdata+DATX_MP2_INBUF),
  224.                                   (ULONG)curr_play->delfcopysize,
  225.                                   DCPF_FROM_AMY|DCPF_XDATA|DCPF_24BIT );
  226.                     Delf_Run( prg_mp2->prog+PROG_MP2_DECODE, 99, DRUNF_ASYNCH,
  227.                               mono,
  228.                               Delf_Peek(prg_pcm->ydata+DATY_PCM_BUFPTR,DMEMF_YDATA),
  229.                               (ULONG)curr_play->II_translate,
  230.                               (ULONG)curr_play->II_jsbound );
  231.                     frames_played++;
  232.                     buffers_filled--;
  233.                     curr_play=curr_play->next;
  234.                 }
  235.                 else decoder_busy++;
  236.                 break;
  237.             case 3:
  238.                 if( !Delf_Peek( prg_mp3->ydata+DATY_MP3_BUSY,DMEMF_YDATA ) )
  239.                 {
  240.                     /*
  241.                     ** send framedata to Delfina and launch MP3 decoder **
  242.                     */
  243.                     if(bitres_ok)
  244.                     {
  245.                         Delf_CopyMem( &bitres_buffer[0],
  246.                                       (void*)(prg_mp3->xdata+DATX_MP3_INBUF),
  247.                                       (ULONG)curr_play->III_main_data_size+33,
  248.                                       DCPF_FROM_AMY|DCPF_XDATA|DCPF_24BIT );
  249.                         Delf_Run( prg_mp3->prog+PROG_MP3_DECODE, 99, DRUNF_ASYNCH,
  250.                                   mono,
  251.                                   Delf_Peek(prg_pcm->ydata+DATY_PCM_BUFPTR,DMEMF_YDATA),
  252.                                   (ULONG)curr_play->modext,
  253.                                   0 );
  254.                     }
  255.                     else maindata_err++;
  256.                     frames_played++;
  257.                     buffers_filled--;
  258.                     curr_play=curr_play->next;
  259.                     if(buffers_filled>0) BitReservoir(curr_play);
  260.                 }
  261.                 else decoder_busy++;
  262.                 break;
  263.             default:
  264.                 break;
  265.             }
  266.         }
  267.         else if(frames_loaded>1) buffers_missed++;
  268.     }
  269. }
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276. /*
  277. **
  278. ** allocate Delfina resources **
  279. **
  280. */
  281. int InitDelfina(void)
  282. {
  283.     if(noplay) return(0);
  284.     pause=1;
  285.  
  286. #ifdef DEBUG
  287.     printf("DEBUG: checkpoint 0  <press return>\n");  getchar();
  288. #endif
  289.  
  290.     if(!(prg_pcm=Delf_AddPrg(&DSP56K_PCM))) {
  291.         printf("**not enough Delfina memory\n");
  292.         return(0);
  293.     }
  294.     Delf_Run(prg_pcm->prog+PROG_PCM_INIT, 0, 0,
  295.             forcemono?1:mono,
  296.             (volume>100) ? (volume*0x7fffff)/200 : (volume*0x400000)/100,
  297.             freq, 0 );
  298.  
  299. #ifdef DEBUG
  300.     printf("DEBUG: checkpoint 1  <press return>\n");  getchar();
  301. #endif
  302.  
  303.     switch(layer)
  304.     {
  305.         case 2:
  306.             if(!nofastl)
  307.                 mem_il_mp2=Delf_AllocMem(INTL_MP2_DATL, DMEMF_LDATA|DMEMF_INTERNAL|DMEMF_ALIGN_64);
  308.             if(!nofastp)
  309.                 mem_ip_mp2=Delf_AllocMem(INTP_MP2_PROG, DMEMF_PROG|DMEMF_INTERNAL);
  310.             if(!(prg_mp2=Delf_AddPrg(&DSP56K_MP2)))
  311.             {
  312.                 printf("**not enough Delfina memory\n");
  313.                 return(0);
  314.             }
  315. #ifdef DEBUG
  316.     printf("DEBUG: checkpoint 2 (mp2)  <press return>\n");  getchar();
  317. #endif
  318.             Delf_Run(prg_mp2->prog+PROG_MP2_INIT, 0, 0,
  319.                      mem_il_mp2, mem_ip_mp2, 0, 0);
  320.             if((!mem_il_mp2 && !nofastl) || (!mem_ip_mp2 && !nofastp))
  321.             {
  322.                 printf("**warning: not enough internal DSP memory\n"
  323.                        "  (the decoder might run too slowly and produce \"jerky\" sound)\n");
  324.             }
  325. #ifdef DEBUG
  326.     printf("DEBUG: checkpoint 3 (mp2)  <press return>\n");  getchar();
  327. #endif
  328.             Delf_Poke(prg_mp2->ydata+DATY_MP2_FORCEMONO, DMEMF_YDATA, forcemono);
  329.             break;
  330.         case 3:
  331.             if(!nofastl)
  332.                 mem_il_mp3=Delf_AllocMem(INTL_MP3_DATL, DMEMF_LDATA|DMEMF_INTERNAL|DMEMF_ALIGN_64);
  333.             if(!nofastp)
  334.                 mem_ip_mp3=Delf_AllocMem(INTP_MP3_PROG, DMEMF_PROG|DMEMF_INTERNAL);
  335.             mem_x_mp3_ro=Delf_AllocMem(EXTX_MP3_RO,DMEMF_XDATA);
  336.             mem_y_mp3_quantab=Delf_AllocMem(EXTY_MP3_QUANTAB,DMEMF_YDATA);
  337.             prg_mp3=Delf_AddPrg(&DSP56K_MP3);
  338.             if(!prg_mp3 || !mem_x_mp3_ro || !mem_y_mp3_quantab)
  339.             {
  340.                 printf("**not enough Delfina memory\n");
  341.                 return(0);
  342.             }
  343. #ifdef DEBUG
  344.     printf("DEBUG: checkpoint 2 (mp3)  <press return>\n");  getchar();
  345. #endif
  346.             Delf_CopyMem(pow43tab, (void*)(prg_mp3->ydata+DATY_MP3_POW43TAB),
  347.                          8206*4, DCPF_FROM_AMY|DCPF_YDATA|DCPF_32BIT);
  348.             Delf_CopyMem(quantab,  (void*)mem_y_mp3_quantab,
  349.                          512*4,  DCPF_FROM_AMY|DCPF_YDATA|DCPF_32BIT);
  350.             Delf_Run(prg_mp3->prog+PROG_MP3_INIT, 0, 0,
  351.                      mem_il_mp3, mem_ip_mp3,
  352.                      (ULONG)curr_play->freq,
  353.                      (ULONG)mem_x_mp3_ro);
  354.             if((!mem_il_mp3 && !nofastl) || (!mem_ip_mp3 && !nofastp))
  355.             {
  356.                 printf("**warning: not enough internal DSP memory\n"
  357.                        "  (the decoder might run too slowly and produce \"jerky\" sound)\n");
  358.             }
  359. #ifdef DEBUG
  360.     printf("DEBUG: checkpoint 3 (mp3)  <press return>\n");  getchar();
  361. #endif
  362.             Delf_Poke(prg_mp3->xdata+DATX_MP3_QUANTAB_P, DMEMF_XDATA, mem_y_mp3_quantab);
  363.             Delf_Poke(prg_mp3->ydata+DATY_MP3_FORCEMONO, DMEMF_YDATA, forcemono);
  364.             break;
  365.         default:
  366.             printf("**layer %d is not supported\n",layer);
  367.             return(0);
  368.     }
  369.  
  370. #ifdef DEBUG
  371.     printf("DEBUG: checkpoint 4  <press return>\n");  getchar();
  372. #endif
  373.     delfint.is_Code=(void(*)(void))IntServer;
  374.     if (!(key=Delf_AddIntServer(prg_pcm->prog+PROG_PCM_INTKEY,&delfint)))
  375.     {
  376.         printf("**couldn't create interrupt server\n");
  377.         return(0);
  378.     }
  379.  
  380. #ifdef DEBUG
  381.     printf("DEBUG: checkpoint 5  <press return>\n");  getchar();
  382. #endif
  383.     if(!(mod_pcm=Delf_AddModule( DM_Inputs, 0,
  384.                                 DM_Outputs, 1,
  385.                                 DM_Code, prg_pcm->prog+PROG_PCM_MODULE,
  386.                                 DM_Freq, dacrate?dacrate*1000:freq,
  387.                                 DM_Name, "DelfMPEG", 0)))
  388.     {
  389.         printf("**couldn't create DelfModule\n");
  390.         return(0);
  391.     }
  392.  
  393. #ifdef DEBUG
  394.     printf("DEBUG: checkpoint 6 (last one)  <press return>\n");  getchar();
  395. #endif
  396.     return(1);
  397. }
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405. /*
  406. **
  407. ** free Delfina resources **
  408. **
  409. */
  410. void CleanupDelfina(void)
  411. {
  412.     Delay(10);
  413.     if(mod_pcm) {Delf_RemModule(mod_pcm); mod_pcm=NULL;}
  414.     if(key)     {Delf_RemIntServer(key); key=0;}
  415.     if(prg_mp2) {Delf_RemPrg(prg_mp2); prg_mp2=NULL;}
  416.     if(prg_mp3) {Delf_RemPrg(prg_mp3); prg_mp3=NULL;}
  417.     if(prg_pcm) {Delf_RemPrg(prg_pcm); prg_pcm=NULL;}
  418.     if(mem_il_mp2) {Delf_FreeMem(mem_il_mp2,DMEMF_LDATA|DMEMF_INTERNAL); mem_il_mp2=NULL;}
  419.     if(mem_ip_mp2) {Delf_FreeMem(mem_ip_mp2,DMEMF_PROG |DMEMF_INTERNAL); mem_ip_mp2=NULL;}
  420.     if(mem_il_mp3) {Delf_FreeMem(mem_il_mp3,DMEMF_LDATA|DMEMF_INTERNAL); mem_il_mp3=NULL;}
  421.     if(mem_ip_mp3) {Delf_FreeMem(mem_ip_mp3,DMEMF_PROG |DMEMF_INTERNAL); mem_ip_mp3=NULL;}
  422.     if(mem_x_mp3_ro) {Delf_FreeMem(mem_x_mp3_ro,DMEMF_XDATA); mem_x_mp3_ro=NULL;}
  423.     if(mem_y_mp3_quantab) {Delf_FreeMem(mem_y_mp3_quantab,DMEMF_YDATA); mem_y_mp3_quantab=NULL;}
  424. }
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431. UWORD GetBits(UWORD num)
  432. {
  433.     UWORD val=0;
  434.     for(; num>0; num--)
  435.     {
  436.         if(gb_num==0)
  437.         {
  438.             gb_buf= *gb_pt++;
  439.             gb_num= 16;
  440.         }
  441.         gb_num--;
  442.         val+= val;
  443.         val|= (gb_buf>>gb_num)&1;
  444.     }
  445.     return(val);
  446. }
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453. UWORD CheckHeader(struct loadbuf *lb)
  454. {
  455.     UWORD result=0;
  456.  
  457.     /** let's ignore these header infos (we don't need them here)
  458.     *** ->version, ->extension, ->copyright, ->original, ->emphasis **/
  459.     lb->header  = currheader;
  460.     lb->layer   = 4-((currheader>>17)&0x3);
  461.     lb->mode    = ((currheader>>6)&0x3);
  462.     lb->modext  = ((currheader>>4)&0x3);
  463.     lb->br_ind  = ((currheader>>12)&0xf);
  464.     lb->freq    = ((currheader>>10)&0x3);
  465.     lb->errprot = ((currheader>>16)&0x1)^0x1;
  466.  
  467.     if( (lb->layer==4)  ||
  468.         (lb->br_ind==0) ||
  469.         (lb->br_ind==15)||
  470.         (lb->freq==3)   )   result+=1;
  471.     if(prevheader)
  472.         if( (currheader&HDR_CONSTANT)!=(prevheader&HDR_CONSTANT) ||
  473.             ((lb->mode==MPG_MD_MONO?1:2)!=channels) ) result+=2;
  474.     if((currheader&HDR_MPEG1)!=HDR_MPEG1) result+=4;
  475.     return(result);
  476. }
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483. /*
  484. **
  485. ** analyze frame header and load frame **
  486. **
  487. */
  488. int ReadFrame(struct loadbuf *lb)
  489. {
  490.     LONG s0,s1,i0,i1;
  491.     UWORD md;
  492.  
  493.     if((md=CheckHeader(lb)))
  494.     {
  495.         if(!prevheader)     /* don't try to resync before the first frame! */
  496.         {
  497.             printf("**not recognized as MPEG1 audio\n");
  498.             return(0);
  499.         }
  500.  
  501.         if((currheader&0xffffff00)==ID3V1) printf(" (ID3v1 tag)\n");
  502.         else
  503.         {
  504.             if(md&4)      printf(" (lost frame sync - non-audio data)\n");
  505.             else if(md&1) printf(" (invalid frame header)\n");
  506.             else if(md&2) printf(" (unsupported frame header change)\n");
  507.             if(verbose)
  508.                 printf("**position=0x%08lx  currheader=0x%08lx  "
  509.                    "prevheader=0x%08lx\n",bytes_loaded,currheader,prevheader);
  510.         }
  511.  
  512.         if(!strict)
  513.         {
  514.             s0=0;
  515.             while((s0<32*1024) && md)
  516.             {
  517.                 bytes_loaded++; s0++;
  518.                 currheader<<=8;
  519.                 i0=ReadCharAsync(file);
  520.                 if(i0<0) break;
  521.                 else
  522.                 {
  523.                     currheader|=i0;
  524.                     md=CheckHeader(lb);
  525.                 }
  526.             }
  527.             printf("**skipped %d bytes - resync %s.\n",s0,md?"failed":"ok");
  528.         }
  529.  
  530.         if(md) return(0);   /* resync failed */
  531.     }
  532.  
  533.  
  534.     if(channels==0) channels=(lb->mode==MPG_MD_MONO)?1:2;
  535.     lb->II_translate= mpg_translate [lb->freq]
  536.                                     [(lb->mode==MPG_MD_MONO)?1:0]
  537.                                     [lb->br_ind];
  538.     lb->II_jsbound= (lb->mode==MPG_MD_JOINT_STEREO) ?
  539.                             (lb->modext<<2)+4 : mpg_sblimit[lb->II_translate];
  540.  
  541.     lb->framesize = (mpg_bitrate[lb->layer-1][lb->br_ind]*144000)
  542.                     /mpg_freq[lb->freq] + ((currheader>>9)&0x1); /* padding */
  543.     lb->delfcopysize = lb->framesize-4;
  544.  
  545.     s0=i0=2;
  546.     if(lb->errprot)
  547.     {
  548.         i0=ReadAsync(file,&lb->crc,s0);
  549.         lb->delfcopysize-=s0;
  550.     }
  551.     s1=i1=lb->delfcopysize;
  552.     if(lb->layer>1) i1=ReadAsync(file,&lb->data[0],s1); /* no layer I !! */
  553.  
  554.     if(!((i0==s0) && (i1==s1)))
  555.     {
  556.         if((i0==-1) || (i1==-1))
  557.             printf(" (file read error)\n");
  558.         else
  559.             if(verbose) printf(" (unexpected EOF - got %d of %d bytes)\n",i1,s1);
  560.         return(0);
  561.     }
  562.  
  563.     if(lb->layer==3)
  564.     {
  565.         gb_pt= (UWORD*)&lb->data[2]; gb_num=0;
  566.         if(lb->mode==MPG_MD_MONO)
  567.         {
  568.             GetBits(9+5+4-16);
  569.             md=GetBits(12);
  570.         }
  571.         else
  572.         {
  573.             GetBits(9+3+8-16);
  574.             md=GetBits(12);
  575.             GetBits(59-12);
  576.             md+=GetBits(12);
  577.             GetBits(59-12);
  578.             md+=GetBits(12);
  579.         }
  580.         GetBits(59-12);
  581.         md+=GetBits(12);
  582.         lb->III_main_data_size=(md+7)>>3;
  583.  
  584.         if(lb->mode!=MPG_MD_JOINT_STEREO) lb->modext=0;
  585.         if(lb->modext&1) frames_js++;
  586.  
  587.         if(buffers_filled==0) BitReservoir(lb);
  588.     }
  589.  
  590.     buffers_filled++;
  591.     frames_loaded++;
  592.     bytes_loaded+=lb->framesize;
  593.  
  594.     return(1);
  595. }
  596.  
  597.  
  598.  
  599.  
  600.     
  601.  
  602.  
  603. int main(void)
  604. {
  605.     struct RDArgs *rdargs;
  606.     LONG args[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}, r1, i, taskpri;
  607.     UBYTE **files_pt, *filename;
  608.     double duration, duration2;
  609.     ULONG sigs, minutes, seconds, millisec, curr_print_pos, prev_print_pos;
  610.     struct timeval time1,time2;
  611.     struct rtFileRequester *rtfilereq=NULL;
  612.     struct rtFileList *rtfilelist=NULL, *rtfilelist_curr=NULL;
  613.     BPTR lock_newdir=NULL, lock_olddir=NULL;
  614.  
  615.     /*
  616.     **
  617.     ** read args **
  618.     **
  619.     */
  620.     rdargs=ReadArgs(template,args,NULL);
  621.     printf("\33[1m%s by Smack/Infect!\33[0m\n",&version[6]);
  622.     files_pt=(char**)args[0];
  623.     verbose=args[1];
  624.     noplay=args[2];
  625.     showtag=args[3];
  626.     nofastl=args[4];
  627.     nofastp=args[5];
  628.     if(args[6]) framebuf=(*(LONG*)args[6]); else framebuf=DEFAULT_FRAMEBUF;
  629.     if(args[7]) asyncbuf=(*(LONG*)args[7]); else asyncbuf=DEFAULT_ASYNCBUF;
  630.     if(args[8]) ffskip=(*(LONG*)args[8]); else ffskip=DEFAULT_FFSKIP;
  631.     notimer=args[9];
  632.     forcemono=args[10];
  633.     strict=args[11];
  634.     if(args[12]) dacrate=(*(LONG*)args[12]); else dacrate=0;
  635.     if(args[13]) volume=(*(LONG*)args[13]); else volume=100;
  636.  
  637.     if(verbose)
  638.         printf(
  639.         "\n"
  640.         "  DelfMPEG - MPEG audio player for Delfina DSP\n"
  641.         "  Copyright (C) 1999, 2000  Michael Henke\n"
  642.         "\n"
  643.         "  This program is free software; you can redistribute it and/or modify\n"
  644.         "  it under the terms of the GNU General Public License as published by\n"
  645.         "  the Free Software Foundation; either version 2 of the License, or\n"
  646.         "  (at your option) any later version.\n"
  647.         "\n"
  648.         "  This program is distributed in the hope that it will be useful,\n"
  649.         "  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  650.         "  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  651.         "  GNU General Public License for more details.\n"
  652.         "\n"
  653.         "  You should have received a copy of the GNU General Public License\n"
  654.         "  along with this program; if not, write to the Free Software\n"
  655.         "  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
  656.         "\n"  );
  657.  
  658.  
  659.     /*
  660.     **
  661.     ** open libraries & stuff **
  662.     **
  663.     */
  664.     if(!noplay)
  665.     {
  666.         ULONG delfina_model;
  667.         double delfina_dspclock;
  668.         if (!(DelfinaBase=OpenLibrary("delfina.library",4))) {
  669.             printf("**unable to open delfina.library V4\n");
  670.             rc=20;
  671.             goto exit_clean;
  672.         }
  673.         delfina_model=Delf_GetAttr(DA_HWInfo,0);
  674.         delfina_model&=0xff; i=0;
  675.         while(delfina_model) { delfina_model>>=1; i++; }
  676.         delfina_model=i ? (i-1) : 7;
  677.         if((DelfinaBase->lib_Version==4) && (DelfinaBase->lib_Revision<12))
  678.             delfina_dspclock=0.0;
  679.         else
  680.             delfina_dspclock=(double)Delf_GetAttr(DA_DSPClock,0)/1000000.0;
  681.         if(verbose)
  682.             printf("\n  Delfina %s: delfina.library v%d.%d, %d K memory, %.1f MHz DSP\n",
  683.                    delfina_name[delfina_model],
  684.                    DelfinaBase->lib_Version,
  685.                    DelfinaBase->lib_Revision,
  686.                    (Delf_AvailMem(DMEMF_PROG|DMEMF_TOTAL)+Delf_AvailMem(DMEMF_YDATA|DMEMF_TOTAL)+1023)>>10,
  687.                    delfina_dspclock );
  688.     }
  689.     if (!(AsyncIOBase=OpenLibrary("asyncio.library",39))) {
  690.         printf("**unable to open asyncio.library V39\n");
  691.         rc=20;
  692.         goto exit_clean;
  693.     }
  694.     TimerBase=(struct Library*)FindName(&SysBase->DeviceList,"timer.device");
  695.     mytask=FindTask(NULL);
  696.     if(!(fib=AllocDosObject(DOS_FIB,&tag_done)))
  697.     {
  698.         rc=20;
  699.         goto exit_clean;
  700.     }
  701.  
  702.     /*
  703.     **
  704.     ** init load buffers **
  705.     **
  706.     */
  707.     if(framebuf<4) framebuf=4;
  708.     if(asyncbuf<4) asyncbuf=4;
  709.     if(ffskip<1) ffskip=1;
  710.     if(dacrate<0) dacrate=0;
  711.     if(dacrate>48) dacrate=48;
  712.     if(dacrate) dacrate=Delf_GetAttr(DA_Freq,dacrate*1000)/1000;
  713.     if(volume<0) volume=0;
  714.     if(volume>200) volume=200;
  715.     framebuf0size=framebuf*(LONG)sizeof(struct loadbuf);
  716.     if(verbose)
  717.         printf( "\n   reader: framebuf=%d (%d K), asyncbuf=%d K, ffskip=%d, strict=o%s\n"
  718.                 "  decoder: forcemono=o%s, dacrate=%d kHz, volume=%d%%\n",
  719.                 framebuf, (framebuf0size+1023)>>10, asyncbuf, ffskip, strict?"n":"ff",
  720.                 forcemono?"n":"ff", dacrate, volume );
  721.     if(!(framebuf0=(struct loadbuf*)AllocMem(framebuf0size,MEMF_PUBLIC)))
  722.     {
  723.         printf("**not enough memory for \"framebuf\"\n");
  724.         rc=20;
  725.         goto exit_clean;
  726.     }
  727.     for(i=0;i<framebuf-1;i++) framebuf0[i].next= &framebuf0[i+1];
  728.     framebuf0[framebuf-1].next=framebuf0;
  729.  
  730.  
  731.     /*
  732.     **
  733.     ** reqtools filerequester if no files specified **
  734.     **
  735.     */
  736.     if(!files_pt)
  737.     {
  738.         if((ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38)))
  739.         {
  740.             if(!(rtfilereq=rtAllocRequest(RT_FILEREQ,NULL)))
  741.             {
  742.                 rc=10;
  743.                 goto exit_clean;
  744.             }
  745.         }
  746.         else
  747.         {
  748.             rc=5;
  749.             goto exit_clean;
  750.         }
  751.     }
  752.  
  753. next_filereq:
  754.     if(rtfilereq)
  755.     {
  756.         rtfilelist=rtFileRequest( rtfilereq, &rtfilename[0],
  757.                                   "DelfMPEG: select MPEG audio files",
  758.                                   RTFI_Flags, FREQF_MULTISELECT|FREQF_PATGAD,
  759.                                   TAG_DONE );
  760.         if(rtfilelist)
  761.         {
  762.             rtfilelist_curr=rtfilelist;
  763.             if(rtfilereq->Dir)
  764.             {
  765.                 lock_newdir=Lock(rtfilereq->Dir,SHARED_LOCK);
  766.                 lock_olddir=CurrentDir(lock_newdir);
  767.             }
  768.         }
  769.         else goto exit_clean;
  770.     }
  771.  
  772.     /*
  773.     **
  774.     ** files loop **
  775.     **
  776.     */
  777.     do
  778.     {
  779.         /*
  780.         **
  781.         ** get next filename **
  782.         **
  783.         */
  784.         if(rtfilelist)
  785.         {
  786.             if(rtfilelist_curr)
  787.             {
  788.                 filename=rtfilelist_curr->Name;
  789.                 rtfilelist_curr=rtfilelist_curr->Next;
  790.             }
  791.             else filename=NULL;
  792.         }
  793.         else filename=(*files_pt++);
  794.         if(!filename) break;
  795.         printf("\n  file: %s\n",filename);
  796.  
  797.         prev_print_pos=curr_print_pos=0;
  798.         curr_load=curr_play=framebuf0;
  799.         bytes_loaded=buffers_filled=buffers_missed=0;
  800.         prevheader=currheader=channels=0;
  801.         frames_loaded=frames_played=0;
  802.         decoder_busy=maindata_err=frames_js=0;
  803.         bitres_offset=0;
  804.  
  805.         /*
  806.         **
  807.         ** open file **
  808.         **
  809.         */
  810.         if((file=OpenAsync(filename,MODE_READ,asyncbuf<<10)))
  811.         {
  812.             /*
  813.             **
  814.             ** read first frame + output some info **
  815.             **
  816.             */
  817.             ExamineFH(file->af_File,fib);
  818.             bytes_total=fib->fib_Size;
  819.             ReadAsync(file,&currheader,4);
  820.  
  821.             if((currheader&0xFFFFFF00)==ID3V2)  /* found ID3V2 tag */
  822.             {
  823.                 UBYTE b[6];
  824.                 ReadAsync(file,&b[0],6);
  825.                 r1=(LONG)b[5] |(LONG)b[4]<<7 |(LONG)b[3]<<14 |(LONG)b[2]<<21;
  826.                 SeekAsync(file,r1,MODE_CURRENT);
  827.                 r1+=10;
  828.                 if(verbose)
  829.                     printf("  skipped ID3v2.%d.%d tag (%d bytes)\n",
  830.                             currheader&0xFF, b[0], r1);
  831.                 bytes_loaded+=r1;
  832.                 ReadAsync(file,&currheader,4);
  833.             }
  834.  
  835.             if(ReadFrame(curr_load))    /* recognize the MPEG audio file */
  836.             {
  837.                 if(showtag)
  838.                 {
  839.                     LONG oldpos;
  840.                     oldpos=SeekAsync(file, -128, MODE_END);
  841.                     ID3v1_TAG=0; havetag=0;
  842.                     ReadAsync(file, &ID3v1_TAG, 3);
  843.                     if((ID3v1_TAG&0xffffff00)==ID3V1)
  844.                     {
  845.                         ReadAsync(file,&ID3v1_buffer[00],30); /* title  */
  846.                         ReadAsync(file,&ID3v1_buffer[31],30); /* artist */
  847.                         ReadAsync(file,&ID3v1_buffer[62],30); /* album  */
  848.                         ReadAsync(file,&ID3v1_buffer[93],04); /* year   */
  849.                         ReadAsync(file,&ID3v1_buffer[98],30); /* comment*/
  850.                         ReadAsync(file,&ID3v1_buffer[141],1); /* genre  */
  851.                         for(i=0;i<124;i++)
  852.                         {
  853.                             if(ID3v1_buffer[i]<0x20) ID3v1_buffer[i]=0x20;
  854.                         }
  855.                         ID3v1_buffer[30]=0x00;
  856.                         ID3v1_buffer[30+1+30]=0x00;
  857.                         ID3v1_buffer[30+1+30+1+30]=0x00;
  858.                         ID3v1_buffer[30+1+30+1+30+1+4]=0x00;
  859.                         ID3v1_buffer[30+1+30+1+30+1+4+1+30]=0x00;
  860.                         havetag=1;
  861.                     }
  862.                     SeekAsync(file, oldpos, MODE_START);
  863.                 }
  864.  
  865.                 {   /* look for Xing VBR header */
  866.                     UBYTE *xpt;
  867.                     xingvbr=0;
  868.                     xpt= &curr_load->data[0];
  869.                     xpt+=(curr_load->mode==MPG_MD_MONO) ? 17 : 32;
  870.                     if((xpt[0]=='X') &&
  871.                        (xpt[1]=='i') &&
  872.                        (xpt[2]=='n') &&
  873.                        (xpt[3]=='g') )
  874.                     {
  875.                         xingvbr++;
  876.                         xpt+=4;
  877.                         xing_flags= (ULONG)xpt[0]<<24 | (ULONG)xpt[1]<<16 |
  878.                                     (ULONG)xpt[2]<<8  | (ULONG)xpt[3];
  879.                         xpt+=4;
  880.                         if(xing_flags&XING_FLAG_FRAMES)
  881.                             xing_frames=(ULONG)xpt[0]<<24 | (ULONG)xpt[1]<<16 |
  882.                                         (ULONG)xpt[2]<<8  | (ULONG)xpt[3];
  883.                         else xing_frames=0;
  884.                         if(verbose) printf("  Xing VBR header found (info: %d frames)\n",xing_frames);
  885.  
  886.                     }
  887.                 }
  888.  
  889.                 freq=mpg_freq[curr_load->freq];
  890.                 mono=(curr_load->mode==MPG_MD_MONO) ? 1 : 0;
  891.                 layer=curr_load->layer;
  892.  
  893.                 duration=(double)bytes_total/((double)freq/1152.0)/(double)curr_load->framesize;
  894.                 r1=mpg_bitrate[layer-1][curr_load->br_ind];
  895.                 if(xingvbr && xing_frames)
  896.                 {
  897.                     duration=(double)xing_frames*1152.0/(double)freq;
  898.                     r1=(LONG)((double)bytes_total/duration/125.0);
  899.                 }
  900.                 printf("  type: layer %s  %s%03d kbps  %ld Hz  %s\n",
  901.                         mpg_layername[layer-1],
  902.                         (xingvbr && xing_frames) ? "VBR avg. " : "",
  903.                         r1,
  904.                         freq,
  905.                         mpg_modename[curr_load->mode] );
  906.                 millisec=(ULONG)(1000.0*modf(duration,&duration2));
  907.                 minutes=(ULONG)(duration2/60.0);
  908.                 seconds=(ULONG)(duration2-minutes*60.0);
  909.                 printf("  time: %02ld min %02ld.%03ld sec\n",minutes,seconds,millisec);
  910.                 if(verbose) printf("  filesize/framesize: %ld/%ld bytes\n",bytes_total,curr_load->framesize);
  911.  
  912.                 if(showtag && havetag)
  913.                 {
  914.                     printf( "  TAG ID3v1\n      title: %s\n     artist: %s\n"
  915.                             "      album: %s\n    comment: %s\n"
  916.                             "       year: %s    genre: %d\n",
  917.                             &ID3v1_buffer[00], /* title  */
  918.                             &ID3v1_buffer[31], /* artist */
  919.                             &ID3v1_buffer[62], /* album  */
  920.                             &ID3v1_buffer[98], /* comment*/
  921.                             &ID3v1_buffer[93], /* year   */
  922.                             (int)ID3v1_buffer[141] ); /* genre  */
  923.                 }
  924.  
  925.                 prevheader=currheader;
  926.                 curr_load=curr_load->next;
  927.  
  928.                 if(InitDelfina())
  929.                 {
  930.                     printf("  playing..."); fflush(stdout);
  931.                     taskpri=SetTaskPri(mytask,9);
  932.                     GetSysTime(&time1);
  933.                     pause=0;
  934.                     /*
  935.                     **
  936.                     ** frames loop **
  937.                     **
  938.                     */
  939.                     while(!ende)
  940.                     {
  941.                         sigs=mytask->tc_SigRecvd;
  942.                         if(sigs&SIGBREAKF_CTRL_C)
  943.                         {
  944.                             printf(" break CTRL-C\n");
  945.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_C;
  946.                             break;  /* exit frames loop */
  947.                         }
  948.                         if(sigs&SIGBREAKF_CTRL_D)
  949.                         {
  950.                             ende=1;
  951.                             printf(" break CTRL-D\n");
  952.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_D;
  953.                             break;  /* exit frames loop */
  954.                         }
  955.                         if(sigs&SIGBREAKF_CTRL_E)
  956.                         {
  957.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_E;
  958.                             if(pause)
  959.                             {
  960.                                 pause=0;
  961.                                 printf("\n  playing...");
  962.                             }
  963.                             else
  964.                             {
  965.                                 pause=1;
  966.                                 printf(" pause");
  967.                             }
  968.                             fflush(stdout);
  969.                         }
  970.                         if(sigs&SIGBREAKF_CTRL_F)
  971.                         {
  972.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_F;
  973.                             pause++;
  974.                             i=ffskip;
  975.                             while((buffers_filled>0) && (i>0))
  976.                             {
  977.                                 curr_play=curr_play->next;
  978.                                 buffers_filled--; i--;
  979.                                 frames_played++;
  980.                                 if((layer==3) && (buffers_filled>0))
  981.                                     BitReservoir(curr_play);
  982.                             }
  983.                             pause--;
  984.                         }
  985.                         if( (buffers_filled<framebuf) &&
  986.                             (bytes_loaded<bytes_total) )
  987.                         {
  988.                             if(ReadAsync(file,&currheader,4)==4)
  989.                                 if(ReadFrame(curr_load))
  990.                                 {
  991.                                     prevheader=currheader;
  992.                                     curr_load=curr_load->next;
  993.                                 }
  994.                                 else bytes_loaded=bytes_total; /* force EOF */
  995.                             else bytes_loaded=bytes_total;
  996.                         }
  997.                         else
  998.                         {
  999.                             if( (bytes_loaded>=bytes_total) &&
  1000.                                 (frames_played>=frames_loaded) )
  1001.                             {
  1002.                                 printf(" done.\n");
  1003.                                 break;  /* exit frames loop */
  1004.                             }
  1005.  
  1006.                             if(!notimer)    /* print timer */
  1007.                             {
  1008.                                 curr_print_pos=(frames_played*1152)/freq;
  1009.                                 if(prev_print_pos!=curr_print_pos)
  1010.                                 {
  1011.                                     prev_print_pos=curr_print_pos;
  1012.                                     printf("\r  playing... (%02d:%02d)",
  1013.                                         curr_print_pos/60, curr_print_pos%60);
  1014.                                     fflush(stdout);
  1015.                                 }
  1016.                             }
  1017.                             Delay(1);
  1018.                         }
  1019.                     }
  1020.                     pause=1; /* mute output */
  1021.                     GetSysTime(&time2);
  1022.                     SetTaskPri(mytask,taskpri);
  1023.                     SubTime(&time2,&time1);
  1024.                     millisec=(ULONG)((double)time2.tv_micro/1000.0);
  1025.                     minutes=(ULONG)((double)time2.tv_secs/60.0);
  1026.                     seconds=(ULONG)((double)time2.tv_secs-minutes*60.0);
  1027.                     duration2=(double)time2.tv_secs+(double)time2.tv_micro/1000000.0;
  1028.                     if(verbose)
  1029.                     {
  1030.                         if(buffers_missed>5) /* prevent "unnecessary" warnings */
  1031.                             printf("**note: detected NO_INPUT_DATA %d times\n",buffers_missed);
  1032.                         if(decoder_busy>0)
  1033.                             printf("**note: detected DECODER_BUSY %d times (%d%%)\n",decoder_busy,decoder_busy*100/frames_played);
  1034.                         if(maindata_err>0)
  1035.                             printf("**note: detected MP3_MAINDATA_ERROR %d times\n",maindata_err);
  1036.                         if(frames_js>0)
  1037.                             printf("**note: unsupported INTENSITY_STEREO frames: %d (%d%%)\n",frames_js,frames_js*100/frames_loaded);
  1038.                         printf("  frames played/loaded: %ld/%ld\n",frames_played,frames_loaded);
  1039.                         printf("  elapsed time: %02ld min %02ld.%03ld sec\n",minutes, seconds, millisec);
  1040.                     }
  1041.                 }
  1042.                 CleanupDelfina();
  1043.             }
  1044.             CloseAsync(file);
  1045.         }
  1046.         else printf("**unable to open file\n");
  1047.     } while(!ende);
  1048.  
  1049.     if(rtfilelist)
  1050.     {
  1051.         if(lock_olddir) { CurrentDir(lock_olddir); lock_olddir=NULL; }
  1052.         if(lock_newdir) { UnLock(lock_newdir); lock_newdir=NULL; }
  1053.         rtFreeFileList(rtfilelist); rtfilelist=NULL;
  1054.         if(!ende) goto next_filereq;
  1055.     }
  1056.  
  1057. exit_clean:
  1058.     if(rdargs) FreeArgs(rdargs);
  1059.     if(framebuf0) FreeMem((APTR)framebuf0,framebuf0size);
  1060.     if(fib) FreeDosObject(DOS_FIB,fib);
  1061.     if(rtfilereq) rtFreeRequest(rtfilereq);
  1062.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  1063.     if(AsyncIOBase) CloseLibrary(AsyncIOBase);
  1064.     if(DelfinaBase) CloseLibrary(DelfinaBase);
  1065.     return(rc);
  1066. }
  1067.